﻿using System;
using System.Linq;
using System.Data.Linq;
using System.Data.Linq.SqlClient;
using System.Collections.Generic;
using WebHoiChoMuaBan.Models;
using WebHoiChoMuaBan.Controllers.Utility;

namespace WebHoiChoMuaBan.Controllers.Helpers
{
    public class MemberHelper : HelperBase
    {
        private Member member = null;

        public Member Member
        {
            get { return member; }
            set { member = value; }
        }

        public MemberHelper(int memberId)
            : base()
        {
            getMember(memberId);
        }

        public MemberHelper()
            : base()
        {
        }

        public struct MemberResult
        {
            public int id;
            public string avatar;
            public string fullname;
            public string email;
            public string cellphone;
            public int uppoint;
            public string memtype;
            public char? status;
        }

        public Member getMember(int id)
        {
            this.member = this.dataContext.Members.SingleOrDefault(m => m.MemId == id);

            if (this.member != null)
                this.member.IsEdit = true;
            return this.member;
        }

        public Member getMemberforDelete(int id)
        {
            Member mem = this.dataContext.Members.SingleOrDefault(m => m.MemId == id);

            if (mem != null)
                mem.IsEdit = true;
            return mem;
        }

        public MemberList getNewMembers(int page, int rowPerPage)
        {

            IQueryable<MemberResult> newMembers = from m in this.dataContext.Members
                                                  join t in this.dataContext.MemberTypes
                                                  on m.MemTypeId equals t.MemTypeId
                                                  where SqlMethods.DateDiffDay(m.MemJoinDate, DateTime.Now.Date) == 0
                                                  orderby m.MemJoinDate descending
                                                  select new MemberResult
                                                  {
                                                      id = m.MemId,
                                                      avatar = m.MemAvatar,
                                                      fullname = m.MemFullname,
                                                      email = m.MemEmail,
                                                      cellphone = m.MemCellPhone,
                                                      uppoint = m.MemUpPoint,
                                                      memtype = t.MemTypeName,
                                                      status = m.MemStatus
                                                  };
            return CreateListMember(page, rowPerPage, newMembers);
        }

        public MemberList getGoldMembers(int page, int rowPerPage)
        {

            IQueryable<MemberResult> newMembers = from m in this.dataContext.Members
                                                  join t in this.dataContext.MemberTypes
                                                  on m.MemTypeId equals t.MemTypeId
                                                  where t.MemTypeName.Equals("Vàng")
                                                  orderby m.MemFullname ascending
                                                  select new MemberResult
                                                  {
                                                      id = m.MemId,
                                                      avatar = m.MemAvatar,
                                                      fullname = m.MemFullname,
                                                      email = m.MemEmail,
                                                      cellphone = m.MemCellPhone,
                                                      uppoint = m.MemUpPoint,
                                                      memtype = t.MemTypeName,
                                                      status = m.MemStatus
                                                  };
            return CreateListMember(page, rowPerPage, newMembers);
        }

        public MemberList getLockedMembers(int page, int rowPerPage)
        {
            IQueryable<MemberResult> newMembers = from m in this.dataContext.Members
                                                  join t in this.dataContext.MemberTypes
                                                  on m.MemTypeId equals t.MemTypeId
                                                  where m.MemStatus == (char?)Member.Status.Locked
                                                  orderby m.MemFullname ascending
                                                  select new MemberResult
                                                  {
                                                      id = m.MemId,
                                                      avatar = m.MemAvatar,
                                                      fullname = m.MemFullname,
                                                      email = m.MemEmail,
                                                      cellphone = m.MemCellPhone,
                                                      uppoint = m.MemUpPoint,
                                                      memtype = t.MemTypeName,
                                                      status = m.MemStatus
                                                  };
            return CreateListMember(page, rowPerPage, newMembers);
        }

        public MemberList getAllMembers(int page, int rowPerPage)
        {
            IQueryable<MemberResult> newMembers = from m in this.dataContext.Members
                                                  join t in this.dataContext.MemberTypes
                                                  on m.MemTypeId equals t.MemTypeId
                                                  orderby m.MemFullname ascending
                                                  select new MemberResult
                                                  {
                                                      id = m.MemId,
                                                      avatar = m.MemAvatar,
                                                      fullname = m.MemFullname,
                                                      email = m.MemEmail,
                                                      cellphone = m.MemCellPhone,
                                                      uppoint = m.MemUpPoint,
                                                      memtype = t.MemTypeName,
                                                      status = m.MemStatus
                                                  };
            return CreateListMember(page, rowPerPage, newMembers);
        }

        public List<WebHoiChoMuaBan.Models.Member> getAllMembers()
        {
            return (from e in base.dataContext.Members select e).ToList<WebHoiChoMuaBan.Models.Member>();
        }

        public MemberList getActiveMembers(int page, int rowPerPage)
        {
            IQueryable<MemberResult> newMembers = from m in this.dataContext.Members
                                                  join t in this.dataContext.MemberTypes
                                                  on m.MemTypeId equals t.MemTypeId
                                                  where m.MemStatus == (char?)Member.Status.Active
                                                  orderby m.MemFullname ascending
                                                  select new MemberResult
                                                  {
                                                      id = m.MemId,
                                                      avatar = m.MemAvatar,
                                                      fullname = m.MemFullname,
                                                      email = m.MemEmail,
                                                      cellphone = m.MemCellPhone,
                                                      uppoint = m.MemUpPoint,
                                                      memtype = t.MemTypeName,
                                                      status = m.MemStatus
                                                  };
            return CreateListMember(page, rowPerPage, newMembers);
        }

        private MemberList CreateListMember(int page, int rowPerPage, IQueryable<MemberResult> newMembers)
        {
            List<MemberResult> pagedNewMemers = newMembers.Skip((page - 1) * rowPerPage).Take(rowPerPage).ToList();

            int totalPages = (int)Math.Ceiling((double)newMembers.Count() / rowPerPage);

            MemberList lstMem = new MemberList(totalPages);
            Member mem;
            foreach (var i in pagedNewMemers)
            {
                mem = new Member();
                mem.MemId = i.id;
                mem.MemFullname = i.fullname;
                mem.MemEmail = i.email;
                mem.MemAvatar = i.avatar;
                mem.MemCellPhone = i.cellphone;
                mem.MemUpPoint = i.uppoint;
                mem.MemberType = new MemberType();
                mem.MemberType.MemTypeName = i.memtype;
                mem.MemStatus = i.status;
                lstMem.Add(mem);

            }
            return lstMem;
        }

        public List<News> getNewNews(int page, int rowPerPage)
        {
            var hNews = new WebHoiChoMuaBan.Controllers.Helpers.NewsHelper(this);
            return (List<News>)hNews.getNewNews(1, 5);
        }

        public IEnumerable<CommentMember> getNewMessages(int page, int rowPerPage)
        {
            IEnumerable<CommentMember> msg = (from m in this.member.CommentsReceive
                                              orderby m.ComDate descending
                                              select m).Skip(page - 1).Take(rowPerPage).AsEnumerable();
            return msg;
        }

        public bool SendMakeFriendRequest(int requestingId)
        {
            MemberHelper hRequestingMember = new MemberHelper(requestingId);
            if (hRequestingMember.member != null)
            {
                FriendList friendList = new FriendList();
                friendList.MemberRequesting = hRequestingMember.member;
                friendList.MemberRequested = this.member;
                friendList.MakeFriendDate = null;
                this.Member.FriendListsRequested.Add(friendList);
                Save();
                return true;
            }
            return false;
        }

        public bool updateMemberCatList(Member mem)
        {
            var tmp = (from e in this.dataContext.Members where e.MemId == mem.MemId select e).SingleOrDefault();
            tmp.MemCategoryList = mem.MemCategoryList;
            tmp.IsEdit = true;
            try
            {
                this.dataContext.SubmitChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        //
        // Insert/Delete Methods

        public Member Login(string username, string password)
        {
            try
            {
                var result = (this.dataContext.Members.Where(x => x.MemUsername == username));
                return result.Where(x => x.MemPassword == new Binary(Security.MD5(password))).FirstOrDefault();
            }
            catch (InvalidOperationException ioex)
            {
                return null;
            }
        }

        public void Add(Member mem)
        {
            this.dataContext.Members.InsertOnSubmit(mem);
        }

        public void Delete(Member mem1)
        {
            Member mem = getMemberforDelete(mem1.MemId);
            this.dataContext.FriendLists.DeleteAllOnSubmit(mem.FriendListsRequested);
            this.dataContext.FriendLists.DeleteAllOnSubmit(mem.FriendListsRequesting);
            this.dataContext.Dislikes.DeleteAllOnSubmit(mem.Dislikes);
            this.dataContext.Advertisments.DeleteAllOnSubmit(mem.Advertisments);
            this.dataContext.BannerAds.DeleteAllOnSubmit(mem.BannerAds);
            this.dataContext.BlackLists.DeleteAllOnSubmit(mem.BlackLists);

            //delete on comreply of owner

            foreach (CommentMember cm in mem.CommentsSend)
            {
                List<CommentMember> cmReply = (from e in this.dataContext.CommentMembers where e.ComIdReply == cm.ComId select e).ToList<CommentMember>();
                this.dataContext.CommentMembers.DeleteAllOnSubmit(cmReply);
            }

            foreach (CommentMember cm in mem.CommentsReceive)
            {
                List<CommentMember> cmReply = (from e in this.dataContext.CommentMembers where e.ComIdReply == cm.ComId select e).ToList<CommentMember>();
                this.dataContext.CommentMembers.DeleteAllOnSubmit(cmReply);
            }

            this.dataContext.CommentMembers.DeleteAllOnSubmit(mem.CommentsReceive);
            this.dataContext.CommentMembers.DeleteAllOnSubmit(mem.CommentsSend);
            this.dataContext.NewsComments.DeleteAllOnSubmit(mem.NewsComments);
            this.dataContext.NewsProductComments.DeleteAllOnSubmit(mem.NewsProductComments);
            this.dataContext.PhotoComments.DeleteAllOnSubmit(mem.PhotoComments);
            this.dataContext.TopicComments.DeleteAllOnSubmit(mem.TopicComments);
            //this.dataContext.Photos.DeleteAllOnSubmit(news.PhotoAlbums);
            this.dataContext.PhotoAlbums.DeleteAllOnSubmit(mem.PhotoAlbums);
            this.dataContext.News.DeleteAllOnSubmit(mem.News);
            this.dataContext.NewsProducts.DeleteAllOnSubmit(mem.NewsProducts);
            this.dataContext.Topics.DeleteAllOnSubmit(mem.Topics);
            this.dataContext.ChatHistories.DeleteAllOnSubmit(mem.ChatHistories);
            this.dataContext.Members.DeleteOnSubmit(mem);
            
            Save();
        }
        public int getCountNewMessage()
        {
            return (from m in this.member.CommentsReceive
                    where ((m.ComDate.Day == DateTime.Now.Day) && (m.ComDate.Month == DateTime.Now.Month)) && (m.ComDate.Year == DateTime.Now.Year)
                    orderby m.ComDate descending
                    select m).ToList<CommentMember>().Count;
        }

        //
        // Persistence

        public void Save()
        {
            this.dataContext.SubmitChanges();
        }

        internal void Refresh(Member mem)
        {
            this.dataContext.Refresh(RefreshMode.OverwriteCurrentValues, mem);
        }
    }

}
